/*
 * Unidata Platform
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 *
 * Commercial License
 * This version of Unidata Platform is licensed commercially and is the appropriate option for the vast majority of use cases.
 *
 * Please see the Unidata Licensing page at: https://unidata-platform.com/license/
 * For clarification or additional options, please contact: info@unidata-platform.com
 * -------
 * Disclaimer:
 * -------
 * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND
 * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
 * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,
 * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND
 * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.
 */
package org.unidata.mdm.dq.core.exception;

import org.apache.commons.lang3.StringUtils;
import org.unidata.mdm.system.exception.DomainId;
import org.unidata.mdm.system.exception.ExceptionId;
import org.unidata.mdm.system.exception.PlatformBusinessException;

/**
 * The Class CleanseFunctionException.
 */
public class CleanseFunctionExecutionException extends PlatformBusinessException {
    /**
     * Serial version UID.
     */
    private static final long serialVersionUID = -8171957635042513810L;
    /**
     * This exception domain.
     */
    private static final DomainId CLEANSE_FUNCTION_EXECUTION_EXCEPTION = () -> "CLEANSE_FUNCTION_EXECUTION_EXCEPTION";
    /**
     * Instantiates a new cleanse function exception.
     */
    public CleanseFunctionExecutionException(String message, Throwable cause, ExceptionId id, Object... args) {
        super(message, cause, id, args);
    }
    /**
     * Constructor.
     * @param message
     * @param id
     * @param args
     */
    public CleanseFunctionExecutionException(String message, ExceptionId id, Object... args) {
        super(message, id, args);
    }

    /**
     * Instantiates a new cleanse function exception.
     * Special form, used by CF implementations.
     *
     * @param cleanseFunctionId
     *            the cleansefunction id
     * @param errorMessages
     *            the error messages
     */
    public CleanseFunctionExecutionException(String cleanseFunctionId, String... errorMessages) {
        this(constructExecMessage(cleanseFunctionId, errorMessages),
                DataQualityExceptionIds.EX_DQ_CLEANSE_FUNCTION_EXEC,
                constructExecArgs(cleanseFunctionId, errorMessages));
    }

    /**
     * Instantiates a new cleanse function exception.
     *
     * @param cleanseFunctionId the cleansefunction id
     * @param cause the cause
     * @param errorMessages the error messages
     */
    public CleanseFunctionExecutionException(String cleanseFunctionId, Throwable cause, String... errorMessages) {
        this(constructExecMessage(cleanseFunctionId, errorMessages),
                cause,
                DataQualityExceptionIds.EX_DQ_CLEANSE_FUNCTION_EXEC,
                constructExecArgs(cleanseFunctionId, errorMessages));
    }

    /**
     * Constructs exec message.
     * @param id CF id
     * @param errors errors
     * @return message
     */
    private static String constructExecMessage(String id, String... errors) {
        return errors == null || errors.length == 0
                ? "Error, while executing cleanse function {}: Unspecified."
                : "Error, while executing cleanse function {}: Details: {}.";
    }
    /**
     * Constructs exec args.
     * @param id CF id
     * @param errors errors
     * @return args
     */
    private static Object[] constructExecArgs(String id, String... errors) {

        final Object[] args = errors == null || errors.length == 0
                ? new Object[1]
                : new Object[2];

        args[0] = id;
        if (errors != null && errors.length > 0) {

            StringBuilder sb = new StringBuilder();
            for (String error : errors) {
                sb.append(StringUtils.LF)
                        .append("- ")
                        .append(error);
            }

            args[1] = sb.toString();
        }

        return args;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public DomainId getDomain() {
        return CLEANSE_FUNCTION_EXECUTION_EXCEPTION;
    }
}
